Skip to content

fix(eve): preserve streamed tool inputs - #2395

Merged
ruiconti merged 6 commits into
mainfrom
e0/338b79b1-ed3d-4b8b-9bfb-205f0df20e79
Aug 27, 2026
Merged

fix(eve): preserve streamed tool inputs#2395
ruiconti merged 6 commits into
mainfrom
e0/338b79b1-ed3d-4b8b-9bfb-205f0df20e79

Conversation

@vercel-gh-bot-3

@vercel-gh-bot-3 vercel-gh-bot-3 Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Summary

A downstream 44k-character reproduction emitted 3,902 tool-input events; repeating the cumulative input in every event made the durable payload about 123,689 KB (measurement). Each action.input.appended event now stores only inputTextDelta and its zero-based UTF-16 code-unit offset. The default reducer accepts contiguous deltas and still exposes cumulative raw input as dynamic-tool.inputText.

Before → after: AI SDK tool-input chunks were ignored until the validated actions.requested event → chunks flow through eve-owned durable append events into the default client reducer, then actions.requested replaces the streaming part with validated input.

Same-call deltas coalesce under backpressure while retaining the first offset. When assistant text precedes a tool call, message.completed is emitted before that call's input events. Filtering for excluded, internal, orphaned, and provider-executed calls is preserved. The message stream advances to version 24, and the seven extension capabilities that expose stream events advance one compatible epoch with retained fixtures.

Validation

Focused protocol, emission, ordered-emitter, and reducer coverage passes with 79 tests. The installed-extension scenario passes with the rebased capability epochs. Keeping stream handling in emission.ts also passes the repository's 700-line invariant.

Checklist

  • This change was requested or approved by a maintainer
  • I ran the relevant checks from CONTRIBUTING.md
  • I added tests and documentation where relevant
  • I added a changeset if this touches the published eve package
  • DCO sign-off passes for every commit (git commit --signoff)

Diff size

Docs — 3 files · +28 / -17

The changeset and two public guides define the versioned delta-and-offset contract and client accumulation behavior.

Implementation — 8 files · +327 / -102

Streamed-input handling remains in the existing harness emission module. The remaining implementation adds the protocol event, ordered coalescing, and reducer projection.

Tests — 19 files · +454 / -2

Focused protocol, harness, emitter, and reducer coverage exercises ordering, coalescing, accumulation, gaps, filtering, and cleanup. Retained extension fixtures and their generated epoch reports account for the remaining test artifacts.

@vercel

vercel Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
eve-docs Ready Ready Preview, v0 Aug 27, 2026 1:47pm
eve-docs-4759 Ready Ready Preview, v0 Aug 27, 2026 1:47pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
eve-pkg Skipped Skipped v0 Aug 27, 2026 1:47pm

@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Bundle + Package Summary: apps/fixtures/weather-agent

Key takeaways

  • No notable deltas vs main (a77ae1b).

Delta vs main (a77ae1b)

Area Metric Baseline Current Delta
Package Packed tarball 8.51 MB 8.51 MB +456 B ⚠️
Package Unpacked publish size 32.12 MB 32.13 MB +10.7 kB ⚠️
Package Installed footprint 75.85 MB 75.86 MB +10.7 kB ⚠️
Package Published files 3563 3565 +2
Package Installed files 7287 7289 +2
Package Installed package instances 35 35 0
Package Distinct installed package names 34 34 0
Package Installed dependency edges 53 53 0
Package Installed optional peer edges 47 47 0
Runtime Unique function payloads 2 2 0
Runtime Total function bytes 18.66 MB 18.67 MB +3.6 kB ⚠️
Runtime Public routes 16 16 0
Changed function payloads vs main (a77ae1b) (2)
Function Status Baseline Current Delta Route changes
functions/__server.func changed 9.33 MB 9.33 MB +1.8 kB ⚠️ none
functions/.well-known/workflow/v1/flow.func changed 9.33 MB 9.33 MB +1.8 kB ⚠️ none

eve init install

Metric Baseline Current Delta
Installed footprint 114.29 MB 114.30 MB +10.7 kB ⚠️
Installed packages 120 120 0
dependencies 4 4 0
devDependencies 2 2 0
Dependency package bytes 46.81 MB 46.82 MB +10.7 kB ⚠️
devDependency package bytes 5.04 MB 5.04 MB 0 B ➖
Build Metadata
  • Preset: vercel
  • Nitro: nitro@3.0.260610-beta
  • Output directory: apps/fixtures/weather-agent/.vercel/output
  • Build metadata timestamp: 2026-08-27T13:48:58.589Z
  • Route aliases: 16 public, 1 internal (17 total aliases)
  • Vercel routes in config: 19
  • Severity legend: 🔴 dominant/large, 🟠 notable, 🟡 watch, ⚪ small
Package Drill-Down

Package Details

  • Package: eve@0.45.2
  • Package directory: packages/eve
  • Tarball: 8.51 MB (eve-0.45.2.tgz)
  • Unpacked payload: 32.13 MB across 3565 published files
  • Installed footprint: 75.86 MB across 7289 installed files
  • Installed root package: 30.78 MB
  • Installed dependencies: 45.08 MB
  • Installed package instances: 35
  • Distinct installed package names: 34
  • Installed dependency edges: 53
  • Installed optional peer edges: 47
  • Runtime dependencies: 2
  • Peer dependencies: 5 (4 optional)

Installed footprint is measured from an isolated temporary npm install of the packed tarball.
Graph metrics read only package.json files in package directories directly beneath a node_modules boundary, including nested boundaries. Each directory is one package instance; distinct names come from those manifests. Dependency edges count each unique name in dependencies or optionalDependencies per instance; optional peer edges count peerDependencies marked optional.

Heavy installed dependencies

  • eve: 30.78 MB (40.6%)
  • @rolldown/binding-linux-x64-gnu: 19.33 MB (25.5%)
  • ai: 6.85 MB (9.0%)
  • zod: 5.07 MB (6.7%)
  • undici: 3.50 MB (4.6%)
Publish payload breakdown
Published file size
🔴 dist/src/compiled/shadcn-registry/index.js       [##############..........] 9.76 MB 30.4%
🟠 dist/src/compiled/@photon-ai/chat-adapter-ime... [###.....................] 2.44 MB 7.6%
🟠 dist/src/compiled/experimental-ai-sdk-code-mo... [##......................] 1.51 MB 4.7%
🟡 dist/src/compiled/@vercel/blob/index.js          [#.......................] 901.8 kB 2.8%
🟡 dist/src/compiled/_chunks/workflow/undici-Dzn... [#.......................] 512.7 kB 1.6%
🔴 Other published files                            [########################] 17.01 MB 52.9%
Installed footprint breakdown
Installed package size
🔴 eve                             [########################] 30.78 MB 40.6%
🔴 @rolldown/binding-linux-x64-gnu [###############.........] 19.33 MB 25.5%
🔴 ai                              [#####...................] 6.85 MB 9.0%
🔴 zod                             [####....................] 5.07 MB 6.7%
🟠 undici                          [###.....................] 3.50 MB 4.6%
🟠 nitro                           [##......................] 2.41 MB 3.2%
🔴 Other installed packages        [######..................] 7.93 MB 10.5%
Runtime dependencies (2)
Package Range Notes
nitro 3.0.260610-beta
undici 8.9.0
Peer dependencies (5)
Package Range Notes
@opentelemetry/api ^1.0.0 optional peer
ai catalog:
braintrust ^3.0.0 optional peer
just-bash ^3.1.0 optional peer
microsandbox ^0.5.0 optional peer
eve init install drill-down

eve init install details

  • Command: eve init my-agent
  • Package manager: npm
  • Installed footprint: 114.30 MB across 9185 installed files
  • Installed packages: 120 total (114 transitive-only)
  • dependencies: 4 direct packages totaling 46.82 MB
  • devDependencies: 2 direct packages totaling 5.04 MB
  • Other transitive package files: 62.44 MB

Installed footprint is measured from an isolated temporary eve init my-agent using the current packed eve tarball.

Heavy installed dependencies

  • eve: 30.78 MB (26.9%)
  • @typescript/typescript-linux-x64: 27.95 MB (24.4%)
  • @rolldown/binding-linux-x64-gnu: 19.33 MB (16.9%)
  • zod: 9.02 MB (7.9%)
  • ai: 6.85 MB (6.0%)
Installed footprint breakdown
Installed package size
🔴 eve                              [########################] 30.78 MB 26.9%
🔴 @typescript/typescript-linux-x64 [######################..] 27.95 MB 24.4%
🔴 @rolldown/binding-linux-x64-gnu  [###############.........] 19.33 MB 16.9%
🔴 zod                              [#######.................] 9.02 MB 7.9%
🔴 ai                               [#####...................] 6.85 MB 6.0%
🟠 undici                           [###.....................] 3.50 MB 3.1%
🔴 Other installed packages         [#############...........] 16.87 MB 14.8%
dependencies (4)
Package Range Installed size Share
@vercel/connect 1.0.0 167.9 kB 0.1%
ai ^7.0.58 6.85 MB 6.0%
eve file:eve-0.45.2.tgz 30.78 MB 26.9%
zod 4.4.3 9.02 MB 7.9%
devDependencies (2)
Package Range Installed size Share
@types/node 24.x 2.54 MB 2.2%
typescript 7.0.2 2.50 MB 2.2%
Function Drill-Down

Payload Size Graph

Unique function payload size and share of total
🔴 functions/.well-known/workflow/v1/flow.func     [########################] 9.33 MB 50.0%
🔴 functions/__server.func                         [########################] 9.33 MB 50.0%

Top Function Payloads

🟠 functions/.well-known/workflow/v1/flow.func • 1 public route • 9.33 MB
Metric Value
Public routes /.well-known/workflow/v1/flow
Runtime nodejs24.x
Handler index.mjs
Payload 9.33 MB
Function files 9.33 MB across 105 files
Traced dependencies 0 B
Signal 🟠 Bundled file index.mjs is 1.93 MB (20.6%)

🟠 🔎 Dependency Analysis

📦 Bundled files:

Bundled file size
🟠 index.mjs                   [###########.............] 1.93 MB 20.6%
🟡 _libs/undici.mjs            [#####...................] 980.5 kB 10.5%
🟡 _chunks/sandbox.mjs         [####....................] 781.9 kB 8.4%
🟡 _chunks/frames-Dl2Hcma4.mjs [####....................] 678.7 kB 7.3%
🟡 _chunks/chatgpt-model.mjs   [####....................] 666.1 kB 7.1%
🔴 Other bundled files         [########################] 4.30 MB 46.1%

🧾 Vercel Config

{
  "handler": "index.mjs",
  "launcherType": "Nodejs",
  "shouldAddHelpers": false,
  "supportsResponseStreaming": true,
  "runtime": "nodejs24.x",
  "maxDuration": "max",
  "experimentalTriggers": [
    {
      "type": "queue/v2beta",
      "topic": "__eve776561746865722d6167656e74_wkf_workflow_*",
      "consumer": "default",
      "retryAfterSeconds": 5,
      "initialDelaySeconds": 0
    }
  ],
  "environment": {
    "WORKFLOW_PRECONDITION_GUARD": "1"
  }
}

🟠 functions/__server.func • 15 public routes, 1 internal alias • 9.33 MB
Metric Value
Public routes /
/eve/v1/callback/[token]
/eve/v1/connections/[name]/callback/[attemptId]/[token]
/eve/v1/connections/[name]/callback/[token]
/eve/v1/health
/eve/v1/info
/eve/v1/session
/eve/v1/session/[parentSessionId]/subagents/[callId]/[childSessionId]/stream
/eve/v1/session/[sessionId]
/eve/v1/session/[sessionId]/cancel
/eve/v1/session/[sessionId]/clear
/eve/v1/session/[sessionId]/compact
/eve/v1/session/[sessionId]/reset
/eve/v1/session/[sessionId]/stream
/eve/v1/task-input/[token]
Internal aliases /__server
Runtime nodejs24.x
Handler index.mjs
Payload 9.33 MB
Function files 9.33 MB across 105 files
Traced dependencies 0 B
Signal 🟠 Bundled file index.mjs is 1.93 MB (20.6%)

🟠 🔎 Dependency Analysis

📦 Bundled files:

Bundled file size
🟠 index.mjs                   [###########.............] 1.93 MB 20.6%
🟡 _libs/undici.mjs            [#####...................] 980.5 kB 10.5%
🟡 _chunks/sandbox.mjs         [####....................] 781.9 kB 8.4%
🟡 _chunks/frames-Dl2Hcma4.mjs [####....................] 678.7 kB 7.3%
🟡 _chunks/chatgpt-model.mjs   [####....................] 666.1 kB 7.1%
🔴 Other bundled files         [########################] 4.30 MB 46.1%

🧾 Vercel Config

{
  "handler": "index.mjs",
  "launcherType": "Nodejs",
  "shouldAddHelpers": false,
  "supportsResponseStreaming": true,
  "runtime": "nodejs24.x"
}

Build Timing: e2e/fixtures/agent-tools-sandbox

This is an informational timing measurement inside eve build, from preflight through publication. Output-size measurement and profile writing are excluded.

Build mode: deployable Vercel build with sandbox template prewarm included.

  • Build pipeline: 3.33 s -> 2.48 s (-857.5 ms) vs main (a77ae1b).
  • Timing is informational: shared GitHub runners are too variable for a hard timing budget.
Detailed phase timings vs `main (a77ae1b)`
Phase Baseline Current Delta
extension.check 12.1 ms 1.2 ms -10.9 ms
project.resolve 0.4 ms 0.3 ms -0.1 ms
workspace.create 0.7 ms 0.6 ms -0.1 ms
host.prepare 1.22 s 452.2 ms -770.2 ms
vercel.service-prefix.resolve 2.1 ms 1.9 ms -0.2 ms
nitro.create 267.6 ms 227.7 ms -39.9 ms
sandbox.prewarm 303.6 ms 287.2 ms -16.4 ms
nitro.cache.prepare 0.3 ms 0.2 ms -0.1 ms
nitro.prepare 0.7 ms 0.7 ms 0.0 ms
nitro.public-assets 0.7 ms 0.7 ms 0.0 ms
nitro.prerender 0.4 ms 0.4 ms 0.0 ms
nitro.bundle 1.46 s 1.44 s -14.6 ms
nitro.cache.write 0.4 ms 0.4 ms 0.0 ms
vercel.workflow-function.materialize 59.6 ms 50.3 ms -9.3 ms
agent-summary.emit 0.7 ms 0.7 ms 0.0 ms
nitro.close 0.1 ms 0.1 ms 0.0 ms
output.publish 2.9 ms 7.4 ms +4.5 ms
workspace.remove 1.8 ms 1.6 ms -0.2 ms

Comment thread packages/eve/src/client/message-reducer-primitives.ts
@cmorbaab

cmorbaab commented Aug 26, 2026

Copy link
Copy Markdown

We've built a downstream backport of this PR onto eve@0.27.2 (our pinned version). It is on a review branch, not yet merged or deployed, but we ran it against a live model to measure it — in case the numbers are useful input.

Retry/replay ordering matches what's documented here. A transient model retry re-runs the stream under a new callId, so a first attempt's input-streaming part can linger until the turn ends; our reducer (ported from this PR) is last-write-wins on inputTextSoFar, and our client always renders the last document-tool part in part order, which is the live one. No ordering surprises in live runs against a real model (Bedrock Claude).

Measured cost, real 15-page document turns, live model (not synthetic):

Every delta emitted (this PR as written) With a 100 ms per-call minimum emit interval
Durable events / turn 4,010 (n=3) 1,828 (n=2)
action.input.appended / turn 3,902 (n=3) 1,721 (n=2)
Durable bytes / turn 123,689 KB 50,844 KB

Because every event carries inputTextSoFar (the full accumulated input, not the delta), bytes grow with the square of document length — one 44k-character document cost 120 MB of durable log even with the interval on. The interval roughly halves it; it doesn't change the growth shape (that would need delta+offset encoding, a bigger change we haven't attempted).

We added a small, additive knob inside consumeStreamContent: a per-call minimum emit interval (env-configurable; we default to 100 ms, 0 reproduces this PR's behavior exactly) that time-gates tool-input-delta emission and flushes unconditionally on every other event, so ordering is unaffected — it uses the same barrier this PR already applies for providerActionBatch.flush(). It measurably halves durable write/storage cost with no reader-visible latency difference in our testing (first-visible-text and reload-catch-up times were within run-to-run noise between the two settings).

Two questions:

  1. Any sense of merge timing? We're carrying this as a patch and would like to drop that maintenance cost.
  2. Would a per-call emit-interval knob (upstream, defaulting to off/0 to preserve today's behavior) be something you'd take as a follow-up PR? Happy to open one.

Matching your event/field names verbatim made the backport a clean, isolated adapter on our side — thanks for the clear design.

vercel-gh-bot-3 Bot and others added 4 commits August 26, 2026 23:40
Co-authored-by: ruiconti <1834568+ruiconti@users.noreply.github.com>
Signed-off-by: Rui Conti <ruiconti@gmail.com>
Co-authored-by: ruiconti <1834568+ruiconti@users.noreply.github.com>
Signed-off-by: Rui Conti <ruiconti@gmail.com>
Co-authored-by: ruiconti <1834568+ruiconti@users.noreply.github.com>
Signed-off-by: Rui Conti <ruiconti@gmail.com>
Signed-off-by: Rui Conti <ruiconti@gmail.com>
Signed-off-by: Rui Conti <ruiconti@gmail.com>
Signed-off-by: Rui Conti <ruiconti@gmail.com>
@ruiconti
ruiconti merged commit 2af4a4c into main Aug 27, 2026
117 checks passed
@ruiconti
ruiconti deleted the e0/338b79b1-ed3d-4b8b-9bfb-205f0df20e79 branch August 27, 2026 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants